#include "binding.h"

#include <valuetype.h>

using namespace core;
using namespace wfnet;

Binding::Binding() :
    m_boundVariables()
{

}

Binding::Binding(const Binding& binding) :
    m_boundVariables()
{
    foreach (const VariableName& variable, binding.m_boundVariables.keys())
    {
        ValueType* copy = dynamic_cast<ValueType* >(
            binding.m_boundVariables[variable]->copy());
        m_boundVariables[variable] = copy;
    }
}

Binding& Binding::operator=(const Binding& other)
{
    if (this != &other)
    {
        foreach (ValueType* old, m_boundVariables)
        {
            delete old;
        }

        m_boundVariables.clear();

        foreach (const VariableName& variable, other.m_boundVariables.keys())
        {           
            ValueType* copy = dynamic_cast<ValueType* >(
                other.m_boundVariables[variable]->copy());
            m_boundVariables[variable] = copy;
        }
    }

    return *this;
}

Binding::~Binding()
{
    foreach (const VariableName& variable, m_boundVariables.keys())
    {
        ValueType* value = m_boundVariables[variable];
        m_boundVariables.remove(variable);

        delete value;
    }
}

void Binding::addBoundVariable(const VariableName& variable,
    const ValueType& value)
{
    if (!m_boundVariables.contains(variable))
    {
        ValueType* copy = dynamic_cast<ValueType* >(value.copy());
        m_boundVariables[variable] = copy;
    }
}

void Binding::removeBoundVariable(const VariableName& variable)
{
    if (m_boundVariables.contains(variable))
    {
        ValueType* value = m_boundVariables[variable];
        m_boundVariables.remove(variable);

        delete value;
    }
}

void Binding::clear()
{
    foreach (ValueType* old, m_boundVariables)
    {
        delete old;
    }

    m_boundVariables.clear();
}

bool Binding::contains(const VariableName& variable) const
{
    return m_boundVariables.contains(variable);
}

const ValueType* Binding::getValue(const VariableName& variable) const
{
    const ValueType* ret = 0;

    if (m_boundVariables.contains(variable))
    {
        ret = m_boundVariables[variable];
    }

    return ret;
}

int Binding::size() const
{
    int ret = m_boundVariables.size();

    return ret;
}
